using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace SteeringBehaviors
{
    class Game
    {
        #region CONSTANTS

        const int veryLargeAsteroids = 15;
        const int largeAsteroids = 25;
        static Random rand = new Random();
        public static object lockObject = new object();
        public static bool syncRender = true;

        #endregion

        #region PRIVATE MEMBERS

        bool drawAsteroids;
        Vector3 bounds;
        BaseObject background;
        List<Asteroid> asteroids;
        List<Team> teams;

        #endregion

        #region PROPERTIES

        /// <summary>
        /// The size of the playing area for this game
        /// </summary>
        public Vector3 Bounds
        {
            get { return bounds; }
            set { bounds = value; Rendering.WorldSize = bounds; }
        }

        /// <summary>
        /// Gets the player team.
        /// </summary>
        /// <remarks>This will return null if no teams are present in this game.</remarks>
        public Team PlayerTeam
        {
            get
            {
                if (teams.Count != 0)
                    return teams[0];
                return null;
            }
        }

        /// <summary>
        /// Determines wether or not asteroids will be drawn.
        /// </summary>
        public bool DrawAsteroids
        {
            get { return drawAsteroids; }
            set { drawAsteroids = value; }
        }

        #endregion

        #region CONSTRUCTORS

        /// <summary>
        /// Default Constructor
        /// </summary>
        public Game()
        {
            asteroids = new List<Asteroid>(veryLargeAsteroids + largeAsteroids);
            // build asteroid field
            for (int i = 0; i < veryLargeAsteroids; ++i)
                asteroids.Add(new Asteroid());
            for (int i = 0; i < largeAsteroids; ++i)
            {
                Asteroid largeAsteroid = new Asteroid();
                largeAsteroid.MaxSpeed = largeAsteroid.MaxSpeed * 2;
                Microsoft.DirectX.Vector3 velocity = largeAsteroid.Velocity;
                velocity.Scale(2);
                largeAsteroid.Velocity = velocity;
                if((rand.Next() & 1) == 1)
                    largeAsteroid.Image = "../Resources/images/asteroids/LAsteroid01.png";
                else
                    largeAsteroid.Image = "../Resources/images/asteroids/LAsteroid02.png";
                largeAsteroid.ImageDimensions = new System.Drawing.Size(64, 64);
                largeAsteroid.Dimensions = new System.Drawing.Size(64, 64);
                asteroids.Add(largeAsteroid);
            }
            teams = new List<Team>();
            bounds = new Vector3();
            background = new BaseObject();
            background.Image = "../Resources/images/backgrounds/moon.jpg";
            background.ImageDimensions = new System.Drawing.Size(2048, 1024);
            background.Dimensions = new System.Drawing.Size(3277, 1638);
            background.Position = new Vector3(800, 600, 0);
            background.DXColor = new ColorValue(.5f, .5f, .5f, 1f);
            DrawAsteroids = false;
        }

        #endregion

        #region INTERFACE METHODS

        /// <summary>
        /// Creates and adds a Team to the game
        /// </summary>
        /// <param name="teamColor">color that will be used to represent the added team</param>
        public void MakeTeam(System.Drawing.Color teamColor)
        {
            teams.Add(new Team());
        }

        /// <summary>
        /// Updates all teams of this game
        /// </summary>
        /// <param name="delta">change in time since last Update call (in seconds)</param>
        public void Update(float delta)
        {
            for (int i = 0; i < asteroids.Count; ++i)
            {
                asteroids[i].Update(delta);
                asteroids[i].BoundsCheck(Bounds);
            }
            for (int i = 0; i < teams.Count; ++i)
            {
                teams[i].Update(delta);
                teams[i].BoundsCheck(Bounds);
            }
        }

        /// <summary>
        /// Renders all objects of this game
        /// </summary>
        /// <param name="sprite">directx sprite object to use for rendering</param>
        public void Render(Microsoft.DirectX.Direct3D.Sprite sprite)
        {
            background.Render(sprite);
            if(DrawAsteroids)
                for (int i = 0; i < asteroids.Count; ++i)
                    asteroids[i].Render(sprite);
            for (int i = 0; i < teams.Count; ++i)
            {
                teams[i].Render(sprite);
            }
        }

        #endregion
    }
}
